#include "wl_trace.h"

#include "wl_core.h"
#include "wl_message_queue.h"
#include "wl_utils.h"

#include <string.h>

#define TRACE_BUF_SIZE 255
#define CUR_WLLOG_LEVEL WLLOG_WARN_LEVEL



// #define OSAL_DEBUG

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

static wl_trace_callback s_trace_callback                        = wl_null;
static wl_char           s_trace_level_name[WLLOG_LEVEL_MAX][10] = {"TRACE", "INFO", "DEBUG", "WARN", "ERROR"};
static wl_bool           s_trace_is_open                         = wl_true;
static wl_uint32         s_trace_level                           = CUR_WLLOG_LEVEL;

#ifdef OSAL_DEBUG
static wl_bool          s_trace_init = wl_false;
static WL_MESSAGE_QUEUE s_trace_queue;
static wl_bool          s_trace_start = wl_false;
#endif

#ifdef OSAL_DEBUG

#endif

void wl_trace_regist_callback(wl_trace_callback callback) {
    s_trace_callback = callback;
#ifdef OSAL_DEBUG
    trace_task_create();
#endif
}

void trace_async_callback(wl_char* buf) {
#ifdef OSAL_DEBUG
    if (s_trace_start) {
        if (0 != wl_message_queue_send(&s_trace_queue, buf, TRACE_BUF_SIZE)) {
            return -1;
        }
    } else {
        if (s_trace_callback) {
            s_trace_callback(buf);
        }
    }
#else
    if (s_trace_callback) {
        s_trace_callback(buf);
    }
#endif
}

void wl_trace_config(wl_bool isopen, wl_uint32 level) {
    s_trace_is_open = isopen;
    s_trace_level   = level;
}

wl_bool wl_trace_is_open(void) {
    return s_trace_is_open;
}

void wl_trace(wl_int32 level, const wl_char* format, ...) {
    if (s_trace_is_open && level >= s_trace_level && level < WLLOG_LEVEL_MAX && wl_null != s_trace_callback) {
        va_list  va;
        wl_char  buf[TRACE_BUF_SIZE + 1] = "";
        wl_int32 buflen                  = 0;

        sprintf(buf, "[%d][%d][WLSDK][%s]:", wl_utctime(), wl_getElapsedTick(), s_trace_level_name[level]);
        buflen = strlen(buf);

        va_start(va, format);
        vsnprintf(buf + buflen, TRACE_BUF_SIZE - buflen, format, va);
        va_end(va);
        buf[TRACE_BUF_SIZE] = '\0';
        trace_async_callback(buf);
    }
}

int wl_trace_weilapb(const wl_char* format, ...) {
    va_list  va;
    wl_char  buf[TRACE_BUF_SIZE + 1] = "";
    wl_int32 buflen                  = 0;

    sprintf(buf, "[%d][%d][WLSDK][ERROR]:", wl_utctime(), wl_getElapsedTick());
    buflen = strlen(buf);

    va_start(va, format);
    vsnprintf(buf + buflen, TRACE_BUF_SIZE - buflen, format, va);
    va_end(va);
    buf[TRACE_BUF_SIZE] = '\0';
    trace_async_callback(buf);
    return 0;
}

#ifdef __cplusplus
}
#endif /* __cplusplus */
